<?php
namespace yphp;

/**
 * Class Where
 * @package yphp
 * where 条件类
 */
final class Where extends Instance
{
    # 条件语句
    protected $where;
    # 绑定数据
    protected $bind = [];
    # id
    static $id = 0;

    // 构造函数
    function construct(){ return false;}

    // 整合条件
    function whereEnd()
    {
        return ['(' . $this->where . ')', $this->bind];
    }

    function where()
    {
        return $this->whereModel(func_get_args(), 'AND');
    }

    function whereOr()
    {
        return $this->whereModel(func_get_args(), 'OR');
    }

    //['id'=>['5,6,7', 'in']]
    private function whereModel($args, $type)
    {
        $field = $args[0];
        if (is_callable($field)) {
            $whereObj = self::instance();
            call_user_func($field, $whereObj);
            list($where, $bind) = $whereObj->whereEnd();
            $this->bind = array_merge($this->bind, $bind);
            $this->saveWhere($where, $type);
        } elseif (is_array($field)) {
            foreach ($field as $k => $v) {
                    is_array($v) ? $this->parse($type, $k, $v[0], key_exists(1, $v) ? $v[1] : '=') : $this->parse($type, $k, $v, '=');
            }
        } else {
            array_unshift($args, $type);
            call_user_func_array([$this, 'parse'], $args);
        }
        return $this;
    }

    // 解析条件
    private function parse($type, $field, $value = null, $op = '=')
    {
        $key = Query::bindKey($field);
        switch ($op = strtoupper($op)) {
            case 'IN':
                $ins = [];
                # 数组[1,2,3] '1,2,3'
                if (in_array($value)) {
                    foreach ($value as $k => $v) {
                        $ins[] = $this->bind($key . '_I' . $k, $v);
                    }
                } else {
                    foreach (explode(',', $value) as $k => $v) {
                        $ins[] = $this->bind($key . '_I' . $k, trim($v));
                    }
                }
                # 统一变成 ( :id_I0_W_ )
                $parse = '(' . join(',', $ins) . ')';
                break;
            case 'BETWEEN':
                # ['141231231,321321321','between'] [[1231231112,321321321],'between']
                list($start, $end) = is_array($value) ? $value : explode(',', $value);
                $parse = "{$this->bind($key.'_BS',trim($start))} AND {$this->bind($key.'_BE',trim($end))}";
                break;
            case 'LIKE':
                # ['keyword','LIKE']
                $parse = $this->bind($key . '_L', $value);
                break;
            default:
                $parse = $this->bind($key, $value);
        }
        return $this->saveWhere(Query::unquote($field) . ' '.$op.' ' . $parse, $type);
    }

    // 写入条件和参数
    private function saveWhere($where, $type)
    {
        $this->where = is_null($w = $this->where) ? '('.$where.')' : "$w $type ($where)";
        return $this;
    }

    // 参数绑定
    private function bind($key, $val)
    {
        $bind = "{$key}_W_" . self::$id++;
        $this->bind[$bind] = $val;
        return $bind;
    }
}